using System;
using Oracle.ManagedDataAccess.Client;
using OracleInternal.Common;
using OracleInternal.TTC;

namespace Oracle.ManagedDataAccess.Types
{
	internal static class TimeStamp
	{
		internal const short DaysPerYear = 365;

		internal const short MaxYear = 9999;

		internal const byte MaxMonth = 12;

		internal const byte MaxDay = 31;

		internal const byte MaxHour = 23;

		internal const byte MaxMinute = 59;

		internal const byte MaxSecond = 59;

		internal const double MaxMillisecond = 999.999999;

		internal const int MaxFSecond = 999999999;

		internal const int MaxTZHours = 14;

		internal const int MaxTZMinutes = 59;

		internal const short MinYear = -4712;

		internal const byte MinMonth = 1;

		internal const byte MinDay = 1;

		internal const byte MinHour = 0;

		internal const byte MinMinute = 0;

		internal const byte MinSecond = 0;

		internal const double MinMillisecond = 0.0;

		internal const byte MinFSecond = 0;

		internal const int MinTZHours = -12;

		internal const int MinTZMinutes = -59;

		internal const byte MaxFSecondPrec = 9;

		internal const byte MinFSecondPrec = 0;

		private const int MaxTZHFormatLength = 6;

		internal const int MinTransYear = 1800;

		internal const byte YEAR = 0;

		internal const byte MONTH = 1;

		internal const byte DAY = 2;

		internal const byte HOUR = 3;

		internal const byte MINUTE = 4;

		internal const byte SECOND = 5;

		internal const byte MILLISECOND = 6;

		internal const byte FSECOND = 7;

		internal const byte TZHOURS = 8;

		internal const byte TZMINUTES = 9;

		internal const byte TIMESPAN = 10;

		internal const byte DAYTOSECOND = 11;

		private const byte DLSBIT = 2;

		private const byte REGLOCBIT = 1;

		private const byte NOTREGLOCBIT = 254;

		private const byte MINLOCBIT = 64;

		private const byte NOTMINLOCBIT = 191;

		private const byte REGIDBIT = 128;

		private const int OFFSET_HOUR = 20;

		private const int OFFSET_MINUTE = 60;

		internal static readonly OracleTimeZone s_timeZoneObj = OracleTimeZone.GetInstance();

		internal static readonly TZInfo LocalTZOffset = GetLocalTZOffset();

		private static int setHighOrderbits(int ID)
		{
			return (ID & 0x1FC0) >> 6;
		}

		private static int setLowOrderbits(int ID)
		{
			return (ID & 0x3F) << 2;
		}

		private static int getHighOrderbits(int hour)
		{
			return (hour & 0x7F) << 6;
		}

		private static int getLowOrderbits(int minute)
		{
			return (minute & 0xFC) >> 2;
		}

		internal static bool IsValidDateTime(int year, int month, int day, int hour, int minute, int second, int nanosecond)
		{
			if (year < -4712 || year > 9999)
			{
				return false;
			}
			if (month < 1 || month > 12)
			{
				return false;
			}
			if (day < 1 || day > 31)
			{
				return false;
			}
			if (hour < 0 || hour > 23)
			{
				return false;
			}
			if (minute < 0 || minute > 59)
			{
				return false;
			}
			if (second < 0 || second > 59)
			{
				return false;
			}
			if (nanosecond < 0 || nanosecond > 999999999)
			{
				return false;
			}
			if (GetDays(month, year) < day)
			{
				return false;
			}
			return true;
		}

		internal static bool IsValidTimeZone(int hourTZ, int minuteTZ)
		{
			if (hourTZ < -12 || hourTZ > 14)
			{
				return false;
			}
			if (minuteTZ < -59 || minuteTZ > 59)
			{
				return false;
			}
			return true;
		}

		internal static string GetZoneName(int zoneId)
		{
			return s_timeZoneObj.GetZoneName(zoneId);
		}

		internal static int GetZoneId(string zoneName)
		{
			return s_timeZoneObj.GetZoneId(zoneName);
		}

		internal static bool IsValidZoneId(int id)
		{
			return s_timeZoneObj.IsValidZoneId(id);
		}

		internal static void InitializelatestTZversion()
		{
			TTCDataTypeNegotiation.s_latestTZVersion = s_timeZoneObj.GetlatestTZversion();
		}

		internal static void ProcessTimeZone(int year, int month, int day, int hour, int minute, int second, ref string timeZone, out int hoursTZ, out int minutesTZ, out int zoneID)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ProcessTimeZone);
			}
			try
			{
				bool flag = true;
				zoneID = -1;
				DateTime? localTime = null;
				if (year >= 1800)
				{
					localTime = new DateTime(year, month, day, hour, minute, second);
				}
				if (timeZone == null)
				{
					TimeZoneInfo local = TimeZoneInfo.Local;
					if (ZoneIdMap.isValidRegion(local.Id))
					{
						zoneID = ZoneIdMap.GetRegionID(local.Id);
					}
					else
					{
						zoneID = s_timeZoneObj.GetZoneId(local.Id);
					}
					if (s_timeZoneObj.IsValidZoneId(zoneID))
					{
						if (!s_timeZoneObj.GetOffsetOfLocalTime(localTime, zoneID, out var offset, out var _))
						{
							throw new OracleException(ResourceStringConstants.ORA_FIELD_NOT_FOUND, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesgWithErrCode(ResourceStringConstants.ORA_FIELD_NOT_FOUND));
						}
						hoursTZ = offset.Hours;
						minutesTZ = offset.Minutes;
						timeZone = s_timeZoneObj.GetZoneName(zoneID);
					}
					else
					{
						if (!localTime.HasValue)
						{
							localTime = ((year <= 0) ? new DateTime?(DateTime.MinValue) : new DateTime?(new DateTime(year, month, day, hour, minute, second)));
						}
						TimeSpan utcOffset = local.GetUtcOffset(localTime.Value);
						hoursTZ = utcOffset.Hours;
						minutesTZ = utcOffset.Minutes;
					}
				}
				else if (timeZone.Contains(":"))
				{
					if (timeZone.Trim()[0] == '-')
					{
						flag = false;
					}
					string[] array = timeZone.Split(':');
					if (array == null || array.Length == 0)
					{
						throw new InvalidTimeZoneException();
					}
					try
					{
						string s = array[0];
						string s2 = array[1];
						hoursTZ = int.Parse(s);
						minutesTZ = int.Parse(s2);
					}
					catch (Exception)
					{
						throw new InvalidTimeZoneException();
					}
					if (!flag)
					{
						minutesTZ = -minutesTZ;
					}
				}
				else
				{
					if (!s_timeZoneObj.IsValidZoneName(timeZone))
					{
						throw new InvalidTimeZoneException();
					}
					zoneID = s_timeZoneObj.GetZoneId(timeZone);
					if (!s_timeZoneObj.GetOffsetOfLocalTime(localTime, zoneID, out var offset2, out var _))
					{
						throw new OracleException(ResourceStringConstants.ORA_FIELD_NOT_FOUND, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesgWithErrCode(ResourceStringConstants.ORA_FIELD_NOT_FOUND));
					}
					hoursTZ = offset2.Hours;
					minutesTZ = offset2.Minutes;
				}
				if (!IsValidTimeZone(hoursTZ, minutesTZ))
				{
					throw new InvalidTimeZoneException();
				}
			}
			catch (Exception ex2)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ProcessTimeZone, ex2);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ProcessTimeZone);
				}
			}
		}

		internal static void GetTimeZoneOffsetInfo(DateTime? date, byte[] byteRep, out int hourTZ, out int minuteTZ, out int zoneID, out bool dst, bool isDataInLocalTime = false, int offset = 0, int length = -1)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetTimeZoneOffsetInfo);
			}
			try
			{
				zoneID = 0;
				dst = false;
				if (length == -1 && byteRep != null)
				{
					length = byteRep.Length - offset;
				}
				if ((byteRep[11 + offset] & 0x80u) != 0)
				{
					zoneID = getHighOrderbits(byteRep[11 + offset]);
					zoneID += getLowOrderbits(byteRep[12 + offset]);
					TimeSpan offset2;
					if (isDataInLocalTime)
					{
						if (!s_timeZoneObj.GetOffsetOfLocalTime(date, zoneID, out offset2, out dst))
						{
							throw new OracleException(ResourceStringConstants.ORA_FIELD_NOT_FOUND, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesgWithErrCode(ResourceStringConstants.ORA_FIELD_NOT_FOUND));
						}
					}
					else
					{
						s_timeZoneObj.GetOffsetOfUTCTime(date, zoneID, out offset2, out dst);
					}
					hourTZ = offset2.Hours;
					minuteTZ = offset2.Minutes;
				}
				else
				{
					hourTZ = (byteRep[11 + offset] & 0xFF) - 20;
					minuteTZ = (byteRep[12 + offset] & 0xFF) - 60;
				}
				if (!IsValidTimeZone(hourTZ, minuteTZ))
				{
					throw new InvalidTimeZoneException();
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetTimeZoneOffsetInfo, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetTimeZoneOffsetInfo);
				}
			}
		}

		internal static int GetFsecond(DateTime date)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetFsecond);
			}
			try
			{
				int year = date.Year;
				int month = date.Month;
				int day = date.Day;
				int hour = date.Hour;
				int minute = date.Minute;
				int second = date.Second;
				DateTime dateTime = new DateTime(year, month, day, hour, minute, second);
				return (int)((date.Ticks - dateTime.Ticks) * 100);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetFsecond, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetFsecond);
				}
			}
		}

		internal static int GetDays(int month, int year)
		{
			int result = 0;
			switch (month)
			{
			case 1:
				result = 31;
				break;
			case 2:
				result = ((!CoreFunctions.IsLeapYear(year)) ? 28 : 29);
				break;
			case 3:
				result = 31;
				break;
			case 4:
				result = 30;
				break;
			case 5:
				result = 31;
				break;
			case 6:
				result = 30;
				break;
			case 7:
				result = 31;
				break;
			case 8:
				result = 31;
				break;
			case 9:
				result = 30;
				break;
			case 10:
				result = 31;
				break;
			case 11:
				result = 30;
				break;
			case 0:
			case 12:
				result = 31;
				break;
			}
			return result;
		}

		internal static int GetDaysBetweenMonth(int lowMonth, int lowDays, int upMonth, int upDays, int year)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetDaysBetweenMonth);
			}
			try
			{
				int num = 0;
				while (lowMonth != upMonth)
				{
					num += DateTime.DaysInMonth((year <= 0) ? ((year < 0) ? (-year) : 4) : year, lowMonth);
					lowMonth++;
				}
				return num - lowDays + upDays;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetDaysBetweenMonth, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetDaysBetweenMonth);
				}
			}
		}

		internal static OracleIntervalDS GetDaysBetweenTimeStamp(byte[] byteRepresentation, int lesserHour, int lesserMinute, int lesserSecond, int lesserNanosecond, int upYear, int upMonth, int upDay, int lowYear, int lowMonth, int lowDay, bool isPositive, OracleDbType oraType)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetDaysBetweenTimeStamp);
			}
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			int num5 = 0;
			int num6 = 0;
			int num7 = 0;
			int num8 = 0;
			try
			{
				switch (oraType)
				{
				case OracleDbType.Date:
					num = OracleDate.GetDateData(byteRepresentation, 3) - 1;
					num2 = OracleDate.GetDateData(byteRepresentation, 4) - 1;
					num3 = OracleDate.GetDateData(byteRepresentation, 5) - 1;
					break;
				default:
					num = GetTSData(byteRepresentation, 3) - 1;
					num2 = GetTSData(byteRepresentation, 4) - 1;
					num3 = GetTSData(byteRepresentation, 5) - 1;
					num4 = GetTSData(byteRepresentation, 7);
					break;
				case OracleDbType.TimeStampTZ:
					num = GetTSTZData(byteRepresentation, 3);
					num2 = GetTSTZData(byteRepresentation, 4);
					num3 = GetTSTZData(byteRepresentation, 5);
					num4 = GetTSTZData(byteRepresentation, 7);
					break;
				}
				num5 = num4 - lesserNanosecond;
				num6 = num3 - lesserSecond;
				num7 = num2 - lesserMinute;
				num8 = num - lesserHour;
				int num9 = CoreFunctions.DateToJulianDays(upYear, upMonth, upDay) - CoreFunctions.DateToJulianDays(lowYear, lowMonth, lowDay);
				if (isPositive)
				{
					return OracleIntervalDS.GetOracleIntervalDS(num9, num8, num7, num6, num5);
				}
				return OracleIntervalDS.GetOracleIntervalDS(-num9, -num8, -num7, -num6, -num5);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetDaysBetweenTimeStamp, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetDaysBetweenTimeStamp);
				}
			}
		}

		internal static OracleIntervalYM GetYearsBetweenTimeStamp(int sumDay, int sumMonth, int sumYear, int passYear, bool isPositive)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetYearsBetweenTimeStamp);
			}
			try
			{
				int num = 0;
				if (sumDay < 0)
				{
					if (sumMonth <= 0)
					{
						sumMonth += 12;
						sumYear--;
					}
					sumDay += DateTime.DaysInMonth((passYear > 0) ? passYear : ((passYear < 0) ? (-passYear) : 4), (sumMonth - 1 == 0) ? 12 : (sumMonth - 1));
					sumMonth--;
				}
				if (sumDay >= 15)
				{
					num = 1;
				}
				sumMonth += num;
				if (sumMonth >= 12)
				{
					sumYear += sumMonth / 12;
					sumMonth %= 12;
				}
				else if (sumMonth < 0)
				{
					sumMonth += 12;
					sumYear--;
				}
				if (isPositive)
				{
					return new OracleIntervalYM(sumYear, sumMonth);
				}
				return new OracleIntervalYM(-sumYear, -sumMonth);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetYearsBetweenTimeStamp, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetYearsBetweenTimeStamp);
				}
			}
		}

		internal static byte[] ConstructTimeStampByteRep(int maxArrSize, int year, int month, int day, int hour, int minute, int second, int nanosecond, int hoursTZ = -1, int minutesTZ = -1, int zoneID = -1)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ConstructTimeStampByteRep);
			}
			try
			{
				byte[] array = new byte[maxArrSize];
				array[0] = (byte)(year / 100 + 100);
				array[1] = (byte)(year % 100 + 100);
				array[2] = (byte)month;
				array[3] = (byte)day;
				array[4] = (byte)(hour + 1);
				array[5] = (byte)(minute + 1);
				array[6] = (byte)(second + 1);
				if (nanosecond != 0)
				{
					array[7] = (byte)(nanosecond >> 24);
					array[8] = (byte)((uint)(nanosecond >> 16) & 0xFFu);
					array[9] = (byte)((uint)(nanosecond >> 8) & 0xFFu);
					array[10] = (byte)((uint)nanosecond & 0xFFu);
				}
				if (maxArrSize > 11)
				{
					if (zoneID > 0)
					{
						array[11] = (byte)setHighOrderbits(zoneID);
						array[11] |= 128;
						array[12] = (byte)setLowOrderbits(zoneID);
					}
					else
					{
						array[11] = (byte)(hoursTZ + 20);
						array[12] = (byte)(minutesTZ + 60);
					}
				}
				return array;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ConstructTimeStampByteRep, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ConstructTimeStampByteRep);
				}
			}
		}

		internal static byte[] ConstructByteArrayTS(int year, int month, int day, int hour, int minute, int second, int nanosecond)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ConstructByteArrayTS);
			}
			try
			{
				return ConstructTimeStampByteRep(11, year, month, day, hour, minute, second, nanosecond);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ConstructByteArrayTS, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ConstructByteArrayTS);
				}
			}
		}

		internal static byte[] ConstructUTCByteArray(int year, int month, int day, int hour, int minute, int second, int nanosecond, int hoursTZ, int minutesTZ, int zoneID)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ConstructUTCByteArray);
			}
			try
			{
				hour -= hoursTZ;
				minute -= minutesTZ;
				AdjustTimeStampValues(ref year, ref month, ref day, ref hour, ref minute, ref second, ref nanosecond);
				return ConstructTimeStampByteRep(13, year, month, day, hour, minute, second, nanosecond, hoursTZ, minutesTZ, zoneID);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ConstructUTCByteArray, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ConstructUTCByteArray);
				}
			}
		}

		internal static byte[] AddYearMonthToTimeStamp(byte[] byteRepresentation, int yearToBeAdded, long monthToBeAdded, OracleDbType oraType)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.AddYearMonthToTimeStamp);
			}
			try
			{
				TSType tsType = ((oraType != OracleDbType.TimeStamp && oraType != OracleDbType.TimeStampLTZ) ? TSType.UtcTimeTZ : TSType.TimeStamp);
				ExtractTimeStampValuesFromByteArray(byteRepresentation, out var year, out var month, out var day, out var hour, out var minute, out var second, out var nanosecond, out var hourTZ, out var minuteTZ, out var zoneID, tsType);
				int num = year + yearToBeAdded;
				long num2 = month + monthToBeAdded;
				if (num2 > 12)
				{
					if ((num += (int)(num2 / 12)) > 9999)
					{
						throw new OverflowException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.YEAR_OUT_OF_RANGE));
					}
					if ((num2 %= 12) == 0L)
					{
						num--;
						num2 = 12L;
					}
				}
				else if (num2 <= 0)
				{
					if ((num += (int)(num2 / 12 - 1)) < -4712)
					{
						throw new OverflowException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.YEAR_OUT_OF_RANGE));
					}
					num2 = num2 % 12 + 12;
				}
				if (num < -4712 || num > 9999)
				{
					throw new OverflowException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.YEAR_OUT_OF_RANGE));
				}
				int num3 = DateTime.DaysInMonth((year > 0) ? year : ((year < 0) ? (-year) : 4), month);
				int num4 = DateTime.DaysInMonth((num > 0) ? num : ((num < 0) ? (-num) : 4), (int)num2);
				year = num;
				month = (int)num2;
				day = ((day == num3 || day > num4) ? num4 : day);
				if (oraType == OracleDbType.TimeStamp || oraType == OracleDbType.TimeStampLTZ)
				{
					return ConstructTimeStampByteRep(11, year, month, day, hour, minute, second, nanosecond);
				}
				return ConstructTimeStampByteRep(13, year, month, day, hour, minute, second, nanosecond, hourTZ, minuteTZ, zoneID);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.AddYearMonthToTimeStamp, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.AddYearMonthToTimeStamp);
				}
			}
		}

		internal static byte[] AddDayTimeToTimeStamp(byte[] byteRepresentation, object value, byte tsComponent, OracleDbType oraType)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.AddDayTimeToTimeStamp);
			}
			try
			{
				TSType tsType = ((oraType != OracleDbType.TimeStamp && oraType != OracleDbType.TimeStampLTZ) ? TSType.UtcTimeTZ : TSType.TimeStamp);
				ExtractTimeStampValuesFromByteArray(byteRepresentation, out var year, out var month, out var day, out var hour, out var minute, out var second, out var nanosecond, out var hourTZ, out var minuteTZ, out var zoneID, tsType);
				int year2 = year;
				long month2 = month;
				long nanoseconds;
				int day2;
				int hour2;
				int minute2;
				int second2;
				switch (tsComponent)
				{
				case 7:
				{
					nanoseconds = nanosecond + (long)value;
					day2 = 0;
					hour2 = 0;
					minute2 = 0;
					second2 = 0;
					int nanosecond2 = 0;
					break;
				}
				case 10:
				{
					TimeSpan timeSpan = (TimeSpan)value;
					day2 = timeSpan.Days;
					hour2 = timeSpan.Hours;
					minute2 = timeSpan.Minutes;
					second2 = timeSpan.Seconds;
					int nanosecond2 = timeSpan.Milliseconds * 1000000;
					nanoseconds = nanosecond + nanosecond2;
					break;
				}
				case 11:
				{
					OracleIntervalDS oracleIntervalDS = (OracleIntervalDS)value;
					day2 = oracleIntervalDS.Days;
					hour2 = oracleIntervalDS.Hours;
					minute2 = oracleIntervalDS.Minutes;
					second2 = oracleIntervalDS.Seconds;
					int nanosecond2 = oracleIntervalDS.Nanoseconds;
					nanoseconds = nanosecond + nanosecond2;
					break;
				}
				default:
				{
					ExtractTimeStampValues((double)value, tsComponent, out day2, out hour2, out minute2, out second2, out var nanosecond2);
					nanoseconds = nanosecond + nanosecond2;
					break;
				}
				}
				int num = 0;
				if (nanoseconds > 999999999 || nanoseconds < 0)
				{
					num = (int)(nanoseconds / 1000000000);
					nanoseconds %= 1000000000;
				}
				long seconds = second + second2 + num;
				num = 0;
				if (seconds > 59 || seconds < 0)
				{
					num = (int)(seconds / 60);
					seconds %= 60;
				}
				long minutes = minute + minute2 + num;
				num = 0;
				if (minutes > 59 || minutes < 0)
				{
					num = (int)(minutes / 60);
					minutes %= 60;
				}
				long hours = hour + hour2 + num;
				num = 0;
				if (hours > 23 || hours < 0)
				{
					num = (int)(hours / 24);
					hours %= 24;
				}
				long days = day + day2 + num;
				if (days > 0)
				{
					while (days > DateTime.DaysInMonth((year2 > 0) ? year2 : ((year2 < 0) ? (-year2) : 4), (int)month2))
					{
						days -= DateTime.DaysInMonth((year2 > 0) ? year2 : ((year2 < 0) ? (-year2) : 4), (int)month2);
						month2++;
						if (month2 > 12)
						{
							if (++year2 > 9999)
							{
								throw new OverflowException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.YEAR_OUT_OF_RANGE));
							}
							month2 = 1L;
						}
					}
				}
				else
				{
					for (; days <= 0; days += DateTime.DaysInMonth((year2 <= 0) ? ((year2 < 0) ? (-year2) : 4) : year2, (int)month2))
					{
						month2--;
						if (month2 <= 0)
						{
							if (--year2 < -4712)
							{
								throw new OverflowException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.YEAR_OUT_OF_RANGE));
							}
							month2 += 12;
						}
					}
				}
				if (month2 <= 0 || days <= 0 || hours < 0 || minutes < 0 || seconds < 0 || nanoseconds < 0)
				{
					GetPositiveTimeStampValues(ref year2, ref month2, ref days, ref hours, ref minutes, ref seconds, ref nanoseconds);
				}
				if (year2 < -4712 || year2 > 9999)
				{
					throw new OverflowException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.YEAR_OUT_OF_RANGE));
				}
				year = year2;
				month = (int)month2;
				day = (int)days;
				hour = (int)hours;
				minute = (int)minutes;
				second = (int)seconds;
				nanosecond = (int)nanoseconds;
				if (oraType == OracleDbType.TimeStamp || oraType == OracleDbType.TimeStampLTZ)
				{
					return ConstructTimeStampByteRep(11, year, month, day, hour, minute, second, nanosecond);
				}
				return ConstructTimeStampByteRep(13, year, month, day, hour, minute, second, nanosecond, hourTZ, minuteTZ, zoneID);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.AddDayTimeToTimeStamp, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.AddDayTimeToTimeStamp);
				}
			}
		}

		internal static void GetPositiveTimeStampValues(ref int year, ref long month, ref long days, ref long hours, ref long minutes, ref long seconds, ref long nanoseconds)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetPositiveTimeStampValues);
			}
			try
			{
				if (nanoseconds < 0)
				{
					nanoseconds += 1000000000L;
					seconds--;
				}
				if (seconds < 0)
				{
					seconds += 60L;
					minutes--;
				}
				if (minutes < 0)
				{
					minutes += 60L;
					hours--;
				}
				if (hours < 0)
				{
					hours += 24L;
					days--;
				}
				if (month <= 0)
				{
					month += 12L;
					year--;
				}
				while (days <= 0)
				{
					days += DateTime.DaysInMonth((year > 0) ? year : ((year < 0) ? (-year) : 4), (int)((month - 1 == 0L) ? 12 : (month - 1)));
					month--;
					if (month <= 0)
					{
						month += 12L;
						year--;
					}
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetPositiveTimeStampValues, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetPositiveTimeStampValues);
				}
			}
		}

		internal static void AdjustTimeStampValues(ref int year, ref int month, ref int days, ref int hours, ref int minutes, ref int seconds, ref int nanoseconds)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.AdjustTimeStampValues);
			}
			try
			{
				if (nanoseconds < 0)
				{
					nanoseconds += 1000000000;
					seconds--;
				}
				if (nanoseconds > 999999999)
				{
					nanoseconds -= 1000000000;
					seconds++;
				}
				if (seconds < 0)
				{
					seconds += 60;
					minutes--;
				}
				if (seconds > 59)
				{
					seconds -= 60;
					minutes++;
				}
				if (minutes < 0)
				{
					minutes += 60;
					hours--;
				}
				if (minutes > 59)
				{
					minutes -= 60;
					hours++;
				}
				if (hours < 0)
				{
					hours += 24;
					days--;
				}
				if (hours > 23)
				{
					hours -= 24;
					days++;
				}
				if (month <= 0)
				{
					month += 12;
					year--;
				}
				if (month > 12)
				{
					month -= 12;
					year++;
				}
				while (days <= 0)
				{
					days += DateTime.DaysInMonth((year > 0) ? year : ((year < 0) ? (-year) : 4), (month - 1 == 0) ? 12 : (month - 1));
					month--;
					if (month <= 0)
					{
						month += 12;
						year--;
					}
				}
				while (days > DateTime.DaysInMonth((year > 0) ? year : ((year < 0) ? (-year) : 4), month))
				{
					days -= DateTime.DaysInMonth((year > 0) ? year : ((year < 0) ? (-year) : 4), month);
					month++;
					if (month > 12)
					{
						month -= 12;
						year++;
					}
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.AdjustTimeStampValues, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.AdjustTimeStampValues);
				}
			}
		}

		internal static int GetTSData(byte[] byteRep, byte tsComponent)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetTSData);
			}
			try
			{
				int num = 0;
				switch (tsComponent)
				{
				case 0:
					num = (byteRep[0] - 100) * 100 + (byteRep[1] - 100);
					break;
				case 1:
					num = byteRep[2] & 0xFF;
					break;
				case 2:
					num = byteRep[3] & 0xFF;
					break;
				case 3:
					num = byteRep[4] & 0xFF;
					break;
				case 4:
					num = byteRep[5] & 0xFF;
					break;
				case 5:
					num = byteRep[6] & 0xFF;
					break;
				case 6:
				case 7:
					num = byteRep[7] << 24;
					num |= byteRep[8] << 16;
					num |= byteRep[9] << 8;
					num |= byteRep[10] & 0xFF;
					if (6 == tsComponent)
					{
						num /= 1000000;
					}
					break;
				}
				return num;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetTSData, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetTSData);
				}
			}
		}

		internal static int GetTSTZData(byte[] byteRep, byte tsComponent)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetTSTZData);
			}
			try
			{
				int num = 0;
				int year = (byteRep[0] - 100) * 100 + (byteRep[1] - 100);
				int month = byteRep[2] & 0xFF;
				int days = byteRep[3] & 0xFF;
				int num2 = (byteRep[4] & 0xFF) - 1;
				int num3 = (byteRep[5] & 0xFF) - 1;
				int seconds = (byteRep[6] & 0xFF) - 1;
				DateTime? date = null;
				if (year >= 1800)
				{
					date = new DateTime(year, month, days, num2, num3, seconds);
				}
				GetTimeZoneOffsetInfo(date, byteRep, out var hourTZ, out var minuteTZ, out var _, out var _);
				num3 += minuteTZ;
				num2 += hourTZ;
				int nanoseconds = 0;
				AdjustTimeStampValues(ref year, ref month, ref days, ref num2, ref num3, ref seconds, ref nanoseconds);
				switch (tsComponent)
				{
				case 0:
					num = year;
					break;
				case 1:
					num = month;
					break;
				case 2:
					num = days;
					break;
				case 3:
					num = num2;
					break;
				case 4:
					num = num3;
					break;
				case 5:
					num = (byteRep[6] & 0xFF) - 1;
					break;
				case 6:
				case 7:
					num = byteRep[7] << 24;
					num |= byteRep[8] << 16;
					num |= byteRep[9] << 8;
					num |= byteRep[10] & 0xFF;
					if (6 == tsComponent)
					{
						num /= 1000000;
					}
					break;
				case 8:
					num = hourTZ;
					break;
				case 9:
					num = minuteTZ;
					break;
				}
				return num;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetTSTZData, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetTSTZData);
				}
			}
		}

		internal static void ExtractTimeStampValues(double data, byte tsComponent, out int day, out int hour, out int minute, out int second, out int nanosecond)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ExtractTimeStampValues);
			}
			try
			{
				decimal num = default(decimal);
				decimal num2 = (decimal)data;
				day = 0;
				hour = 0;
				minute = 0;
				second = 0;
				nanosecond = 0;
				switch (tsComponent)
				{
				case 2:
					day = (int)num2;
					num = num2 - (decimal)day;
					num2 = num * 24m;
					hour = (int)num2;
					num = num2 - (decimal)hour;
					num2 = num * 60m;
					minute = (int)num2;
					num = num2 - (decimal)minute;
					num2 = num * 60m;
					second = (int)num2;
					num = num2 - (decimal)second;
					nanosecond = (int)(num * 1000000000m);
					break;
				case 3:
					hour = (int)num2;
					num = num2 - (decimal)hour;
					num2 = num * 60m;
					minute = (int)num2;
					num = num2 - (decimal)minute;
					num2 = num * 60m;
					second = (int)num2;
					num = num2 - (decimal)second;
					nanosecond = (int)(num * 1000000000m);
					break;
				case 4:
					minute = (int)num2;
					num = num2 - (decimal)minute;
					num2 = num * 60m;
					second = (int)num2;
					num = num2 - (decimal)second;
					nanosecond = (int)(num * 1000000000m);
					break;
				case 5:
					second = (int)num2;
					num = num2 - (decimal)second;
					nanosecond = (int)(num * 1000000000m);
					break;
				case 7:
					nanosecond = (int)data;
					break;
				case 6:
					break;
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ExtractTimeStampValues, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ExtractTimeStampValues);
				}
			}
		}

		internal static void ExtractTimeStampValuesFromByteArray(byte[] binData, out int year, out int month, out int day, out int hour, out int minute, out int second, out int nanosecond, out int hourTZ, out int minuteTZ, out int zoneID, TSType tsType)
		{
			year = (binData[0] - 100) * 100 + (binData[1] - 100);
			month = binData[2] & 0xFF;
			day = binData[3] & 0xFF;
			hour = (binData[4] & 0xFF) - 1;
			minute = (binData[5] & 0xFF) - 1;
			second = (binData[6] & 0xFF) - 1;
			int num = binData[7] << 24;
			num |= binData[8] << 16;
			num |= binData[9] << 8;
			num = (nanosecond = num | (binData[10] & 0xFF));
			minuteTZ = -1;
			hourTZ = -1;
			zoneID = -1;
			if (tsType == TSType.LocalTimeTZ || tsType == TSType.UtcTimeTZ)
			{
				DateTime? date = null;
				if (year >= 1800)
				{
					date = new DateTime(year, month, day, hour, minute, second);
				}
				GetTimeZoneOffsetInfo(date, binData, out hourTZ, out minuteTZ, out zoneID, out var _);
				if (tsType == TSType.LocalTimeTZ)
				{
					minute += minuteTZ;
					hour += hourTZ;
					AdjustTimeStampValues(ref year, ref month, ref day, ref hour, ref minute, ref second, ref nanosecond);
				}
			}
		}

		internal static void ExtractTimeStampTZValuesFromByteArray(byte[] binData, out int year, out int month, out int day, out int hour, out int minute, out int second, out int nanosecond, out int hourTZ, out int minuteTZ, out int zoneID)
		{
			year = (binData[0] - 100) * 100 + (binData[1] - 100);
			month = binData[2] & 0xFF;
			day = binData[3] & 0xFF;
			hour = (binData[4] & 0xFF) - 1;
			minute = (binData[5] & 0xFF) - 1;
			second = (binData[6] & 0xFF) - 1;
			int num = binData[7] << 24;
			num |= binData[8] << 16;
			num |= binData[9] << 8;
			num = (nanosecond = num | (binData[10] & 0xFF));
			minuteTZ = -1;
			hourTZ = -1;
			zoneID = -1;
			DateTime? date = null;
			if ((0x80u & binData[11]) != 0)
			{
				binData[12] &= 254;
				if ((binData[12] & 2) == 0)
				{
				}
			}
			else
			{
				binData[11] &= 191;
			}
			if (year >= 1800)
			{
				date = new DateTime(year, month, day, hour, minute, second);
			}
			GetTimeZoneOffsetInfo(date, binData, out hourTZ, out minuteTZ, out zoneID, out var _, isDataInLocalTime: true);
		}

		internal static TimeSpan GetLTZOffset(byte[] dbTimeZoneBytes, OracleIntervalDS sessionTimeZone)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetLTZOffset);
			}
			try
			{
				int num = 0;
				int num2 = 0;
				TimeSpan t = new TimeSpan(sessionTimeZone.Hours, sessionTimeZone.Minutes, 0);
				num = OracleIntervalDS.GetIDSData(dbTimeZoneBytes, 3);
				num2 = OracleIntervalDS.GetIDSData(dbTimeZoneBytes, 4);
				return new TimeSpan(num, num2, 0) - t;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetLTZOffset, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetLTZOffset);
				}
			}
		}

		internal static byte[] GetAdjustedTimeStampLTZ(byte[] bindata, TimeSpan adjTimeZone, bool isSend)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetAdjustedTimeStampLTZ);
			}
			try
			{
				ExtractTimeStampValuesFromByteArray(bindata, out var year, out var month, out var day, out var hour, out var minute, out var second, out var nanosecond, out var _, out var _, out var _, TSType.TimeStampLTZ);
				if (isSend)
				{
					hour += adjTimeZone.Hours;
					minute += adjTimeZone.Minutes;
				}
				else
				{
					hour -= adjTimeZone.Hours;
					minute -= adjTimeZone.Minutes;
				}
				AdjustTimeStampValues(ref year, ref month, ref day, ref hour, ref minute, ref second, ref nanosecond);
				return ConstructByteArrayTS(year, month, day, hour, minute, second, nanosecond);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetAdjustedTimeStampLTZ, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetAdjustedTimeStampLTZ);
				}
			}
		}

		internal static byte[] GetLocalTimeFromUTCByteRep(byte[] bindata)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetLocalTimeFromUTCByteRep);
			}
			try
			{
				int year = (bindata[0] - 100) * 100 + (bindata[1] - 100);
				int month = bindata[2] & 0xFF;
				int days = bindata[3] & 0xFF;
				int num = (bindata[4] & 0xFF) - 1;
				int num2 = (bindata[5] & 0xFF) - 1;
				int seconds = (bindata[6] & 0xFF) - 1;
				int num3 = bindata[7] << 24;
				num3 |= bindata[8] << 16;
				num3 |= bindata[9] << 8;
				num3 |= bindata[10] & 0xFF;
				DateTime? date = null;
				if (year >= 1800)
				{
					date = new DateTime(year, month, days, num, num2, seconds);
				}
				GetTimeZoneOffsetInfo(date, bindata, out var hourTZ, out var minuteTZ, out var zoneID, out var dst);
				num += hourTZ;
				num2 += minuteTZ;
				AdjustTimeStampValues(ref year, ref month, ref days, ref num, ref num2, ref seconds, ref num3);
				byte[] array = ConstructTimeStampByteRep(13, year, month, days, num, num2, seconds, num3, hourTZ, minuteTZ, zoneID);
				if ((array[11] & 0x80u) != 0)
				{
					array[12] |= 1;
					if (dst)
					{
						array[12] |= 2;
					}
				}
				else
				{
					array[11] |= 64;
				}
				return array;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetLocalTimeFromUTCByteRep, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetLocalTimeFromUTCByteRep);
				}
			}
		}

		internal static void GetUTCByteRepFromLocalArray(byte[] bindata, out byte[] utcArray, out DateTime? dateObj, bool returnAsDateTime = false)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetUTCByteRepFromLocalArray);
			}
			try
			{
				int year = (bindata[0] - 100) * 100 + (bindata[1] - 100);
				int month = bindata[2] & 0xFF;
				int days = bindata[3] & 0xFF;
				int num = (bindata[4] & 0xFF) - 1;
				int num2 = (bindata[5] & 0xFF) - 1;
				int seconds = (bindata[6] & 0xFF) - 1;
				int num3 = bindata[7] << 24;
				num3 |= bindata[8] << 16;
				num3 |= bindata[9] << 8;
				num3 |= bindata[10] & 0xFF;
				utcArray = null;
				dateObj = null;
				if (!returnAsDateTime)
				{
					if ((0x80u & bindata[11]) != 0)
					{
						bindata[12] &= 254;
						if ((bindata[12] & 2) == 0)
						{
						}
					}
					else
					{
						bindata[11] &= 191;
					}
					dateObj = null;
					if (year >= 1800)
					{
						dateObj = new DateTime(year, month, days, num, num2, seconds);
					}
					GetTimeZoneOffsetInfo(dateObj, bindata, out var hourTZ, out var minuteTZ, out var zoneID, out var _, isDataInLocalTime: true);
					num -= hourTZ;
					num2 -= minuteTZ;
					AdjustTimeStampValues(ref year, ref month, ref days, ref num, ref num2, ref seconds, ref num3);
					utcArray = ConstructTimeStampByteRep(13, year, month, days, num, num2, seconds, num3, hourTZ, minuteTZ, zoneID);
				}
				else
				{
					int num4 = 0;
					int millisecond = num3 / 1000000;
					num4 = num3 % 1000000;
					dateObj = new DateTime(year, month, days, num, num2, seconds, millisecond);
					if (num4 > 0)
					{
						dateObj = dateObj.Value.AddTicks(num4 / 100);
					}
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetUTCByteRepFromLocalArray, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetUTCByteRepFromLocalArray);
				}
			}
		}

		internal static void ToUniversalTime(ref int year, ref int month, ref int day, ref int hour, ref int minute, ref int second, ref int nanosecond, ref int hoursTZ, ref int minutesTZ)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ToUniversalTime);
			}
			try
			{
				hour -= hoursTZ;
				minute -= minutesTZ;
				AdjustTimeStampValues(ref year, ref month, ref day, ref hour, ref minute, ref second, ref nanosecond);
				hoursTZ = 0;
				minutesTZ = 0;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ToUniversalTime, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ToUniversalTime);
				}
			}
		}

		internal static OracleTimeStampLTZ ToLocalTime(int year, int month, int day, int hour, int minute, int second, int nanosecond, int hoursTZ, int minutesTZ)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ToLocalTime);
			}
			try
			{
				ToUniversalTime(ref year, ref month, ref day, ref hour, ref minute, ref second, ref nanosecond, ref hoursTZ, ref minutesTZ);
				DateTime? utcTime = null;
				if (year >= 1800)
				{
					utcTime = new DateTime(year, month, day, hour, minute, second);
				}
				int num = -1;
				TimeZoneInfo local = TimeZoneInfo.Local;
				num = ((!ZoneIdMap.isValidRegion(local.Id)) ? s_timeZoneObj.GetZoneId(local.Id) : ZoneIdMap.GetRegionID(local.Id));
				if (s_timeZoneObj.IsValidZoneId(num))
				{
					s_timeZoneObj.GetOffsetOfUTCTime(utcTime, num, out var offset, out var _);
					minute += offset.Minutes;
					hour += offset.Hours;
				}
				else
				{
					if (!utcTime.HasValue)
					{
						utcTime = ((year <= 0) ? new DateTime?(DateTime.MinValue) : new DateTime?(new DateTime(year, month, day, hour, minute, second)));
					}
					TimeSpan utcOffset = local.GetUtcOffset(utcTime.Value);
					minute += utcOffset.Minutes;
					hour += utcOffset.Hours;
				}
				AdjustTimeStampValues(ref year, ref month, ref day, ref hour, ref minute, ref second, ref nanosecond);
				return new OracleTimeStampLTZ(year, month, day, hour, minute, second, nanosecond);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ToLocalTime, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ToLocalTime);
				}
			}
		}

		internal static byte[] ConvertLTZDataToDBTime(byte[] ltzByteArray, OracleTimeZoneInfo? dbTimeZoneBytes, OracleIntervalDS sessionTimeZone)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ConvertLTZDataToDBTime);
			}
			try
			{
				ExtractTimeStampValuesFromByteArray(ltzByteArray, out var year, out var month, out var day, out var hour, out var minute, out var second, out var nanosecond, out var hourTZ, out var minuteTZ, out var zoneID, TSType.TimeStampLTZ);
				int num = 0;
				OracleTimeZoneInfo oracleTimeZoneInfo = ((sessionTimeZone.initialZoneId == 0) ? GetTimeZoneInfo(sessionTimeZone.BinData) : new OracleTimeZoneInfo(sessionTimeZone.initialZoneId, sessionTimeZone.Hours, sessionTimeZone.Minutes));
				int zoneId = oracleTimeZoneInfo.m_zoneId;
				int hoursTZ;
				if (zoneId > 0)
				{
					DateTime? localTime = null;
					if (year >= 1800)
					{
						localTime = new DateTime(year, month, day, hour, minute, second);
					}
					if (!s_timeZoneObj.GetOffsetOfLocalTime(localTime, zoneId, out var offset, out var _))
					{
						throw new OracleException(ResourceStringConstants.ORA_FIELD_NOT_FOUND, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesgWithErrCode(ResourceStringConstants.ORA_FIELD_NOT_FOUND));
					}
					hoursTZ = offset.Hours;
					num = offset.Minutes;
				}
				else
				{
					hoursTZ = oracleTimeZoneInfo.m_tzHours;
					num = oracleTimeZoneInfo.m_tzMinutes;
				}
				ToUniversalTime(ref year, ref month, ref day, ref hour, ref minute, ref second, ref nanosecond, ref hoursTZ, ref num);
				zoneID = dbTimeZoneBytes.Value.m_zoneId;
				if (zoneID > 0)
				{
					DateTime? utcTime = null;
					if (year >= 1800)
					{
						utcTime = new DateTime(year, month, day, hour, minute, second);
					}
					s_timeZoneObj.GetOffsetOfUTCTime(utcTime, zoneID, out var offset2, out var _);
					hourTZ = offset2.Hours;
					minuteTZ = offset2.Minutes;
				}
				else
				{
					hourTZ = dbTimeZoneBytes.Value.m_tzHours;
					minuteTZ = dbTimeZoneBytes.Value.m_tzMinutes;
				}
				hour += hourTZ;
				minute += minuteTZ;
				AdjustTimeStampValues(ref year, ref month, ref day, ref hour, ref minute, ref second, ref nanosecond);
				return ConstructByteArrayTS(year, month, day, hour, minute, second, nanosecond);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ConvertLTZDataToDBTime, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ConvertLTZDataToDBTime);
				}
			}
		}

		internal static void ConvertDBTimeToLTZData(byte[] dbByteArray, OracleTimeZoneInfo? dbTimeZoneBytes, OracleIntervalDS sessionTimeZone, out byte[] byteRep, out DateTime? dateObj, bool returnAsDateTimeObj = false)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ConvertDBTimeToLTZData);
			}
			try
			{
				dateObj = null;
				ExtractTimeStampValuesFromByteArray(dbByteArray, out var year, out var month, out var day, out var hour, out var minute, out var second, out var nanosecond, out var hourTZ, out var minuteTZ, out var zoneID, TSType.TimeStampLTZ);
				zoneID = dbTimeZoneBytes.Value.m_zoneId;
				if (zoneID > 0)
				{
					dateObj = null;
					if (year >= 1800)
					{
						dateObj = new DateTime(year, month, day, hour, minute, second);
					}
					if (!s_timeZoneObj.GetOffsetOfLocalTime(dateObj, zoneID, out var offset, out var _))
					{
						throw new OracleException(ResourceStringConstants.ORA_FIELD_NOT_FOUND, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesgWithErrCode(ResourceStringConstants.ORA_FIELD_NOT_FOUND));
					}
					hourTZ = offset.Hours;
					minuteTZ = offset.Minutes;
				}
				else
				{
					hourTZ = dbTimeZoneBytes.Value.m_tzHours;
					minuteTZ = dbTimeZoneBytes.Value.m_tzMinutes;
				}
				ToUniversalTime(ref year, ref month, ref day, ref hour, ref minute, ref second, ref nanosecond, ref hourTZ, ref minuteTZ);
				int num = 0;
				OracleTimeZoneInfo oracleTimeZoneInfo = ((sessionTimeZone.initialZoneId == 0) ? GetTimeZoneInfo(sessionTimeZone.BinData) : new OracleTimeZoneInfo(sessionTimeZone.initialZoneId, sessionTimeZone.Hours, sessionTimeZone.Minutes));
				int zoneId = oracleTimeZoneInfo.m_zoneId;
				int num2;
				if (zoneId > 0)
				{
					dateObj = null;
					if (year >= 1800)
					{
						dateObj = new DateTime(year, month, day, hour, minute, second);
					}
					s_timeZoneObj.GetOffsetOfUTCTime(dateObj, zoneId, out var offset2, out var _);
					num2 = offset2.Hours;
					num = offset2.Minutes;
				}
				else
				{
					num2 = oracleTimeZoneInfo.m_tzHours;
					num = oracleTimeZoneInfo.m_tzMinutes;
				}
				hour += num2;
				minute += num;
				AdjustTimeStampValues(ref year, ref month, ref day, ref hour, ref minute, ref second, ref nanosecond);
				byteRep = null;
				if (!returnAsDateTimeObj)
				{
					byteRep = ConstructByteArrayTS(year, month, day, hour, minute, second, nanosecond);
					return;
				}
				int num3 = 0;
				int millisecond = nanosecond / 1000000;
				num3 = nanosecond % 1000000;
				dateObj = new DateTime(year, month, day, hour, minute, second, millisecond);
				if (num3 > 0)
				{
					dateObj = dateObj.Value.AddTicks(num3 / 100);
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ConvertDBTimeToLTZData, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.ConvertDBTimeToLTZData);
				}
			}
		}

		internal static TZInfo GetLocalTZOffset()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetLocalTZOffset);
			}
			try
			{
				TimeSpan utcOffset = TimeZoneInfo.Local.GetUtcOffset(DateTime.Now);
				return new TZInfo(utcOffset.Hours, utcOffset.Minutes);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetLocalTZOffset, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetLocalTZOffset);
				}
			}
		}

		internal static OracleTimeZoneInfo GetTimeZoneInfo(byte[] dbTimeZoneBytes)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetTimeZoneInfo);
			}
			try
			{
				int zoneId = -1;
				int tzHours = -1;
				int tzMinutes = -1;
				if (dbTimeZoneBytes[4] > OracleIntervalDS.LDIREGIDFLAG)
				{
					zoneId = RepConversion.GetRegHour(dbTimeZoneBytes[2]);
					zoneId += RepConversion.GetRegMin(dbTimeZoneBytes[3]);
				}
				else
				{
					tzHours = OracleIntervalDS.GetIDSData(dbTimeZoneBytes, 3);
					tzMinutes = OracleIntervalDS.GetIDSData(dbTimeZoneBytes, 4);
				}
				return new OracleTimeZoneInfo(zoneId, tzHours, tzMinutes);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetTimeZoneInfo, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.TimeStamp, OracleTraceFuncName.GetTimeZoneInfo);
				}
			}
		}
	}
}
